package org.jeecg.modules.online.cgform.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.MatchTypeEnum;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
import org.jeecg.common.util.*;
import org.jeecg.common.util.jsonschema.BaseColumn;
import org.jeecg.common.util.jsonschema.CommonProperty;
import org.jeecg.common.util.jsonschema.JsonSchemaDescrip;
import org.jeecg.common.util.jsonschema.JsonschemaUtil;
import org.jeecg.common.util.jsonschema.validate.*;
import org.jeecg.common.util.oss.OssBootUtil;
import org.jeecg.modules.online.cgform.entity.*;
import org.jeecg.modules.online.cgform.enums.CgformValidPatternEnum;
import org.jeecg.modules.online.cgform.mapper.OnlCgformHeadMapper;
import org.jeecg.modules.online.cgform.model.TreeSelectColumn;
import org.jeecg.modules.online.cgform.service.IOnlCgformFieldService;
import org.jeecg.modules.online.config.exception.DBException;
import org.jeecg.modules.online.config.util.DbTableUtil;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.springframework.util.FileCopyUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
public class CgformUtil {

	public static final String SQL_SELECT = "SELECT ";
	public static final String SQL_FROM = " FROM ";
	public static final String SQL_AND = " AND ";
	public static final String SQL_LIKE = " like ";
	public static final String SQL_COUNT = " COUNT(*) ";
	public static final String SQL_WHERE_TRUE = " where 1=1  ";
	public static final String SQL_ORDER = " ORDER BY ";
	public static final String SQL_ASC = "asc";
	public static final String SQL_DESC = "desc";
	public static final String SQL_EQ = "=";
	public static final String SQL_NE = "!=";
	public static final String SQL_GE = ">=";
	public static final String SQL_GT = ">";
	public static final String SQL_LE = "<=";
	public static final String SQL_LT = "<";

	/** online是
	 *   是否 tree
	 *   是否 同步数据库
	 * */
    public static final String STATUS_YES = "Y";

	/**
	 * 复制表 表名后缀分隔符
	 */
	public static final String ONLINE_TABLE_SPLIT_STR = "$";

	/*** 创建时间字段 */
	public static final String CREATE_TIME = "CREATE_TIME";

	/*** 创建人字段 */
	public static final String CREATE_BY="CREATE_BY";

	/*** 修改时间字段 */
	public static final String UPDATE_TIME = "UPDATE_TIME";

	/*** 修改人字段 */
	public static final String UPDATE_BY="UPDATE_BY";

	/*** 部门编码 字段 */
	public static final String SYS_ORG_CODE = "SYS_ORG_CODE";

	/**
	 * 查询条件有折叠功能，此值表示折叠前要显示几个
	 */
	public static final int  QUERY_FIELD_SHOW_NUM = 2;

	/**
	 * 单引号
	 */
	public static final String SQL_SQ = "'";
	/**
	 * SQLERVER中文查询，前面必须加 N
	 */
	public static final String SQLERVER_ZH = "N";
	/**
	 * 逗号
	 */
	public static final String SQL_COMMA = ",";


	/**
 	  * 查询模式 普通查询
	 */
	public static final String QUERY_MODE_SINGLE = "single";

	// 字段dbtype


	/**
	  * 主键字段
	 */
	public static final String P_KEY = "id";
	/**
	 * bpmStatus
	 */
	public static final String BPM_STATUS = "bpm_status";
	public static final String YES = "1";


	public static final String SYNC_FORCE="force";
	public static final String SYNC_NORMAL="normal";

	/**控件类型 开关*/
	public static final String SWITCH = "switch";
	/**控件类型 popup*/
	public static final String POPUP = "popup";
	/**控件类型 image*/
	public static final String IMAGE = "image";
	/**控件类型 自定义树tree*/
	public static final String SEL_TREE = "sel_tree";
	/**控件类型 分类字典树控件 */
	public static final String CAT_TREE = "cat_tree";
	/**控件类型 级联下拉控件 */
	public static final String LINK_DOWN = "link_down";
	/**用户 表名*/
	public static final String USER_TABLE_NAME = "SYS_USER";
	/**用户名称字段名 */
	public static final String USER_REAL_NAME = "REALNAME";
	/**用户账号字段名 */
	public static final String USER_LOGIN_NAME = "USERNAME";
    /**部门 表名*/
    public static final String DEP_TABLE_NAME = "SYS_DEPART";
    /**部门名称字段名 */
    public static final String DEP_TEXT_NAME = "DEPART_NAME";
    /**部门id字段名 */
    public static final String DEP_ID_NAME = "ID";
	/**分类字典表名*/
	public static final String CATEGORY_TABLE_NAME = "SYS_CATEGORY";
	/**分类字典字段名 name*/
	public static final String CATEGORY_TEXT_NAME = "NAME";
	/**分类字典字段名 code*/
	public static final String CATEGORY_CODE_NAME = "CODE";
	/**分类字典字段名 id*/
	public static final String CATEGORY_ID_NAME = "ID";
	/**分类字典字段名 pid*/
	public static final String CATEGORY_PID_NAME = "PID";
	/**分类字典字段名 has_child*/
	public static final String CATEGORY_CHILD_NAME = "HAS_CHILD";

	/**表单搜索控件*/
	public static final String SELECT_SEARCH = "sel_search";

	/**
	 * 子表前缀
	 */
	public static final String SUB_TABLE_PRE = "sub-table-design_";

	/**
	 * java增强的编码 导入
	 */
	public static final String ENHANCE_IMPORT = "import";

	/**
	 * java增强的编码 导出
	 */
	public static final String ENHANCE_EXPORT = "export";

	/**
	 * java增强的编码 查询
	 */
	public static final String ENHANCE_QUERY = "query";

    /**
     * js增强 form
     */
	public static final String ENHANCE_FORM = "form";

    /**
     * js增强 list
     */
    public static final String ENHANCE_LIST = "list";

	/**
	 * java 增强激活状态
	 */
	public static final String ENHANCE_ACTIVE = "1";

	/**
	 * 增强类型 开始事件
	 */
	public static final String ENHANCE_TYPE_START = "start";

	/**
	 * online列表风格erp
	 */
	public static final String ONL_TYPE_ERP = "erp";


	/**
	 * 导出参数名
	 */
	public static final String ONL_EXPORT_ARG = "exportSingleOnly";

	/**
	 * 导入参数名
	 */
	public static final String ONL_IMPORT_ARG = "isSingleTableImport";

	/**
	 * 导入参数名 外键
	 */
	public static final String ONL_IMPORT_FOREIGNKEYS = "foreignKeys";


	/**
	 * online 导入数据标识 走新增逻辑
	 */
	public static final int OL_IMPORT_INSERT = 1;

	/**
	 * online 导入数据标识 走编辑逻辑
	 */
	public static final int OL_IMPORT_UPDATE = 2;

	/**
	 * online 导入数据标识 丢弃
	 */
	public static final int OL_IMPORT_ABD = 0;

	/**
	 * 列表 显示列 标识
	 */
	public static final int SHOW_LIST_YES = 1;

	/**
	 * 删除标识 物理删除
	 */
	public static final String REAL_DELETE="1";

	/**
	 * id列
	 */
	public static final String COLUMN_ID = "id";

	/**
	 * 列居中显示
	 */
	public static final String COLUMN_ALIGN_CENTER = "center";

	/**
	  * 拼装查询动态列表数据的sql 根据配置的列只查询对应的列
	 * @param tbname
	 * @param fieldList
	 * @param sb
	 * @return select A1,A2,...An from tbname
	 */
	public static void getAutoListBaseSql(String tbname,List<OnlCgformField> fieldList,StringBuffer sb) {
		if(fieldList==null || fieldList.size()==0) {
			sb.append(SQL_SELECT+P_KEY);
		}else {
			sb.append(SQL_SELECT);
			int size = fieldList.size();
			boolean has = false;
			for(int i=0;i<size;i++) {
				OnlCgformField item = fieldList.get(i);
				if(P_KEY.equals(item.getDbFieldName())) {
					has = true;
				}
                //update-begin--Author:scott  Date:20190922 for：Online配置字典分类树控件报错，逻辑未处理字段文本为空情况-------------------
				if(CAT_TREE.equals(item.getFieldShowType()) && oConvertUtils.isNotEmpty(item.getDictText())){
					sb.append(item.getDictText()+SQL_COMMA);
				}
                //update-begin--Author:scott  Date:20190922 for：Online配置字典分类树字典报错，逻辑未处理字段文本为空情况-------------------
				if(i==size-1) {
					sb.append(item.getDbFieldName()+" ");
				}else {
					sb.append(item.getDbFieldName()+SQL_COMMA);
				}
			}
			if(!has) {
				sb.append(SQL_COMMA+P_KEY);
			}
		}
		sb.append(SQL_FROM+getRealTableName(tbname));
	}

	/**
	 * oracle处理时间类型的字段需要特殊处理一下
	 * @param value
	 * @return
	 */
	public static String getOracletoDateTimeString(String value) {
		return " to_date('"+value+"','yyyy-MM-dd HH24:mi:ss')";
	}
	/**
	 * oracle处理时间类型的字段需要特殊处理一下
	 * @param value
	 * @return
	 */
	public static String getOracletoDateString(String value) {
		return " to_date('"+value+"','yyyy-MM-dd')";
	}


	/**
	 * 判断是否需要处理字典配置 list+radio+checkbox+list_multi这四项均有字典配置
	 * @param filedShowType
	 * @return
	 */
	public static boolean hasDictConfig(String filedShowType) {
		if("list".equals(filedShowType)) {
			return true;
		}
		if("radio".equals(filedShowType)) {
			return true;
		}
		if("checkbox".equals(filedShowType)) {
			return true;
		}
		if("list_multi".equals(filedShowType)) {
			return true;
		}
		return false;
	}

	/**
	  * 拼装条件
	 * @param params 前端传过来的查询条件
	 * @param fieldList
	 * @return and A1=1 and A2=2 ... and An=n
	 */
	public static String getAutoListConditionSql(List<OnlCgformField> fieldList,Map<String,Object> params,List<String> needList) {
		StringBuffer sb = new StringBuffer();
		String dataBase="";
		try {
			dataBase = DbTableUtil.getDatabaseType();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (DBException e) {
			e.printStackTrace();
		}
		//获取数据权限规则
		Map<String,SysPermissionDataRuleModel> ruleMap = QueryGenerator.getRuleMap();
		//权限规则自定义SQL表达式
		for (String c : ruleMap.keySet()) {
			if(oConvertUtils.isNotEmpty(c) && c.startsWith(QueryGenerator.SQL_RULES_COLUMN)){
				sb.append(SQL_AND+"("+QueryGenerator.getSqlRuleValue(ruleMap.get(c).getRuleValue())+")");
			}
		}
		for (OnlCgformField item : fieldList) {
			String field = item.getDbFieldName();
			String dbtype = item.getDbType();
			//权限查询 兼容下划线和驼峰命名
			if(ruleMap.containsKey(field)) {
				addRuleToStringBuffer(dataBase,ruleMap.get(field), field, dbtype, sb);
			}
			if(ruleMap.containsKey(oConvertUtils.camelNames(field))) {
				addRuleToStringBuffer(dataBase,ruleMap.get(field), field, dbtype, sb);
			}

			//如果needlist 包含这个字段 需要将此字段设置为可单条件查询
			if(needList!=null && needList.contains(field)){
				item.setIsQuery(1);
				item.setQueryMode(QUERY_MODE_SINGLE);
			}

			//如果是外键字段 需要设置为可查询的
			if(oConvertUtils.isNotEmpty(item.getMainField()) && oConvertUtils.isNotEmpty(item.getMainTable())){
				item.setIsQuery(1);
				item.setQueryMode(QUERY_MODE_SINGLE);
			}
			//TODO 此处逻辑存在缺陷，如果页面的字段未配置查询条件，则无法通过此字段进行数据筛选，比如通过deleteFlag字段（for: 想用js增强实现条件查询，不成功 #751）

			//1.判断是否查询
			if(1==item.getIsQuery()) {
				//2.判断是否是简单查询
				if(QUERY_MODE_SINGLE.equals(item.getQueryMode())) {
					Object value = params.get(field);
					if(value!=null) {
						if(DataBaseConstant.DB_TYPE_ORACLE.equals(dataBase) && dbtype.toLowerCase().indexOf("date")>=0) {
							sb.append(SQL_AND+field + SQL_EQ + getOracletoDateTimeString(value.toString()));
						}else {
							boolean isString = !OnlineDbHandler.isNumField(dbtype);
							String fieldCondition = QueryGenerator.getSingleQueryConditionSql(field, "", value, isString);
							sb.append(SQL_AND+fieldCondition);
						}
					}
				}else {
					//范围查询走此逻辑
					Object value_begin =  params.get(field+"_begin");
					if(value_begin!=null) {
						sb.append(SQL_AND+field+SQL_GE);
						if(OnlineDbHandler.isNumField(dbtype)) {
							//如果数字类型直接拼在SQL后面
							sb.append(value_begin.toString());
						}else if(DataBaseConstant.DB_TYPE_ORACLE.equals(dataBase) && dbtype.toLowerCase().indexOf("date")>=0) {
							sb.append(getOracletoDateTimeString(value_begin.toString()));
						}else{
							//如果字符串类型需要加单引号
							sb.append(SQL_SQ+value_begin.toString()+SQL_SQ);
						}
					}
					Object value_end =  params.get(field+"_end");
					if(value_end!=null) {
						sb.append(SQL_AND+field+SQL_LE);
						if(OnlineDbHandler.isNumField(dbtype)) {
							sb.append(value_end.toString());
						}else if(DataBaseConstant.DB_TYPE_ORACLE.equals(dataBase) && dbtype.toLowerCase().indexOf("date")>=0) {
							sb.append(getOracletoDateTimeString(value_end.toString()));
						}else {
							sb.append(SQL_SQ+value_end.toString()+SQL_SQ);
						}
					}
				}
			}

		}
		return sb.toString();
	}

	/**
	 * 获取高级查询条件 SQL，支持主子表查询
	 *
	 * @param requestParams request中携带的参数
	 * @return and A1=1 and A2=2 ... and An=n
	 */
	public static String getAutoListSuperQuerySql(Map<String, Object> requestParams) {
		// 取出查询条件
		Object superQueryParamsObject = requestParams.get("superQueryParams");
		if (superQueryParamsObject == null || StringUtils.isBlank(superQueryParamsObject.toString())) {
			return "";
		}
		IOnlCgformFieldService service = SpringContextUtils.getBean(IOnlCgformFieldService.class);
		String superQueryParams = null;
		try {
			superQueryParams = URLDecoder.decode(superQueryParamsObject.toString(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return "";
		}
		JSONArray params = JSONArray.parseArray(superQueryParams);
		// 取出 matchType
		Object superQueryMatchTypeObject = requestParams.get("superQueryMatchType");
		MatchTypeEnum matchType = MatchTypeEnum.getByValue(superQueryMatchTypeObject);
		if (matchType == null) {
			matchType = MatchTypeEnum.AND;
		}
		// 子表 map
		Map<String, JSONObject> subTablesForeignKeyMap = new HashMap<>();
		// 遍历查询条件，并拼接SQL
		StringBuilder builder = new StringBuilder(SQL_AND).append("(");
		for (int i = 0; i < params.size(); i++) {
			JSONObject parameter = params.getJSONObject(i);
			String field = parameter.getString("field");
			String[] fieldArray = field.split(",");
			// 没有使用逗号分割，说明是主表
			if (fieldArray.length == 1) {
				spliceSuperQueryField(builder, field, parameter, matchType, null, i == 0);
			} else if (fieldArray.length == 2) {
				// 使用了逗号分割，是子表，index 0 = 子表名， index 1 = 子表字段
				String subTableName = fieldArray[0];
				String subFieldName = fieldArray[1];
				JSONObject subTable = subTablesForeignKeyMap.get(subTableName);
				if (subTable == null) {
					List<OnlCgformField> subTableFields = service.queryFormFieldsByTableName(subTableName);
					subTable = new JSONObject(3);
					for (OnlCgformField cgformField : subTableFields) {
						if (StringUtils.isNotBlank(cgformField.getMainTable())) {
							subTable.put("subTableName", subTableName);
							subTable.put("subField", cgformField.getDbFieldName());
							subTable.put("mainTable", cgformField.getMainTable());
							subTable.put("mainField", cgformField.getMainField());
						}
					}
					subTablesForeignKeyMap.put(subTableName, subTable);
				}
				spliceSuperQueryField(builder, subFieldName, parameter, matchType, subTable, i == 0);
			}
		}
		return builder.append(")").toString();
	}


	/**
	 * 拼接高级查询条件字段
	 *
	 * @param builder   拼接对象
	 * @param fieldName 字段名称
	 * @param parameter 其他参数
	 * @param matchType 拼接类型 and or
	 * @param subTable  子表相关字段，传null代表是主表
	 */
	private static void spliceSuperQueryField(StringBuilder builder, String fieldName, JSONObject parameter, MatchTypeEnum matchType, JSONObject subTable, boolean isFirst) {
		if (!isFirst) {
			builder.append(" ").append(matchType.getValue()).append(" ");
		}
		String type = parameter.getString("type");
		String nativeValue = parameter.getString("val");
		String value = formatSuperQueryValue(type, nativeValue);
		QueryRuleEnum rule = QueryRuleEnum.getByValue(parameter.getString("rule"));
		if (rule == null) {
			rule = QueryRuleEnum.EQ;
		}
		// 子表名不为空则查询子表
		if (subTable != null) {
			String subTableName = subTable.getString("subTableName");
			String subField = subTable.getString("subField");
			String mainTable = subTable.getString("mainTable");
			String mainField = subTable.getString("mainField");
			builder.append("(").append(mainField).append(" IN (SELECT ").append(subField).append(" FROM ").append(subTableName).append(" WHERE ").append(fieldName);
			setSuperQueryFieldByRule(builder, rule, nativeValue, value, type);
			builder.append("))");
		} else {
			builder.append(fieldName);
			setSuperQueryFieldByRule(builder, rule, nativeValue, value, type);
		}
	}

	private static void setSuperQueryFieldByRule(StringBuilder builder, QueryRuleEnum rule, String nativeValue, String value, String type) {
		//针对oracle数据库，时间值进行特殊处理
		if ("date".equals(type)) {
			if (DataBaseConstant.DB_TYPE_ORACLE.equalsIgnoreCase(getDatabseType())) {
				value = value.replace("'", "");
				if (value.length() == 10) {
					value = getOracletoDateString(value);
				} else {
					value = getOracletoDateTimeString(value);
				}
			}
		}

		switch (rule) {
			case GT: // 大于
				builder.append(SQL_GT).append(value);
				break;
			case GE: // 大于等于
				builder.append(SQL_GE).append(value);
				break;
			case LT: // 小于
				builder.append(SQL_LT).append(value);
				break;
			case LE: // 小于等于
				builder.append(SQL_LE).append(value);
				break;
			case NE: // 不等于
				builder.append(SQL_NE).append(value);
				break;
			case IN: // 在...中
				builder.append(" IN (");
				String[] arr = nativeValue.split(",");
				for (int i = 0; i < arr.length; i++) {
					String str = arr[i];
					if (StringUtils.isNotBlank(str)) {
						String val = formatSuperQueryValue(type, str);
						builder.append(val);
						if (i < arr.length - 1) {
							builder.append(SQL_COMMA);
						}
					}
				}
				builder.append(")");
				break;
			case LIKE: // 包含
				builder.append(SQL_LIKE).append(SQLERVER_ZH).append(SQL_SQ).append("%").append(nativeValue).append("%").append(SQL_SQ);
				break;
			case LEFT_LIKE: // 以..结尾
				builder.append(SQL_LIKE).append(SQLERVER_ZH).append(SQL_SQ).append("%").append(nativeValue).append(SQL_SQ);
				break;
			case RIGHT_LIKE: // 以..开始
				builder.append(SQL_LIKE).append(SQLERVER_ZH).append(SQL_SQ).append(nativeValue).append("%").append(SQL_SQ);
				break;
			case EQ: // 等于 （默认值）
			default:
				builder.append(SQL_EQ).append(value);
		}
	}

	/** 高级查询格式化value，字符类型加上双引号，数值类型直接返回 */
	private static String formatSuperQueryValue(String type, String value) {
		if ("int".equals(type) || "number".equals(type)) {
			return value;
		}else if ("date".equals(type)) {
			return SQL_SQ + value + SQL_SQ;
		}else {
			if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDatabseType())){
				return 'N'+SQL_SQ + value + SQL_SQ;
			}else{
				return SQL_SQ + value + SQL_SQ;
			}
		}
	}

	/**
	  * 获取页面查询参数
	 * @param request
	 * @return
	 */
	public static Map<String, Object> getParameterMap(HttpServletRequest request) {
		// 参数Map
		Map<?, ?> properties = request.getParameterMap();
		// 返回值Map
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Iterator<?> entries = properties.entrySet().iterator();

		Map.Entry<String, Object> entry;
		String name = "";
		String value = "";
		Object valueObj =null;
		while (entries.hasNext()) {
			entry = (Map.Entry<String, Object>) entries.next();
			name = (String) entry.getKey();
			valueObj = entry.getValue();
			if ("_t".equals(name) || null == valueObj) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	/**
	  * 判断字段是否有效
	 */
	public static boolean existFieldName(String fieldName,List<OnlCgformField> fieldList) {
		for (OnlCgformField f : fieldList) {
			if(fieldName.equals(f.getDbFieldName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 根据字段集合组装JSON schema
	 * @param fieldList 有效的列
	 * @param disabledFieldNameList 被禁用的列名称
	 * @param treeColumn 树形列表用到 表示被展示为树形下拉的列
	 * @return
	 */
	public static JSONObject getJsonSchemaByCgformFieldList(List<OnlCgformField> fieldList,List<String> disabledFieldNameList,TreeSelectColumn treeColumn) {
		JSONObject json = new JSONObject();
		List<String> required = new ArrayList<String>();
		List<CommonProperty> props = new ArrayList<CommonProperty>();
		ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
		OnlCgformHeadMapper mapper = SpringContextUtils.getBean(OnlCgformHeadMapper.class);
		//级联下拉，已经加载的不再加载
		List<String> excludeFields = new ArrayList<String>();
		for (OnlCgformField item : fieldList) {
			String field = item.getDbFieldName();
			if(P_KEY.equals(field)) {
				continue;
			}
			if(excludeFields.contains(field)){
                continue;
            }
			String title = item.getDbFieldTxt();
			//获取required
			if(YES.equals(item.getFieldMustInput())) {
				required.add(field);
			}
			String filedShowType = item.getFieldShowType();

			CommonProperty prop = null;
			//update-begin-author:taoyan for:TASK #3386 【严重bug】下拉字段设置为数字类型，控件出不来
			if(SWITCH.equals(filedShowType)){
				prop = new SwitchProperty(field, title, item.getFieldExtendJson());
			}else if(hasDictConfig(filedShowType)) {
				List<DictModel> include = new ArrayList<DictModel>();
				if(oConvertUtils.isNotEmpty(item.getDictTable())) {
					include = sysBaseAPI.queryTableDictItemsByCode(item.getDictTable(), item.getDictText(), item.getDictField());
				}else if(oConvertUtils.isNotEmpty(item.getDictField())) {
					include = sysBaseAPI.queryDictItemsByCode(item.getDictField());
				}
				prop = new StringProperty(field, title, filedShowType, item.getDbLength(), include);
				if(OnlineDbHandler.isNumField(item.getDbType())){
					prop.setType("number");
				}
			}else if(OnlineDbHandler.isNumField(item.getDbType())) {
				NumberProperty numProp = new NumberProperty(field, title, "number");
				if(CgformValidPatternEnum.INTEGER.getType().equals(item.getFieldValidType())) {
					numProp.setPattern(CgformValidPatternEnum.INTEGER.getPattern());
				}
				prop = numProp;
			}else {
		    //update-end-author:taoyan for:TASK #3386 【严重bug】下拉字段设置为数字类型，控件出不来
				if(POPUP.equals(filedShowType)){
					PopupProperty popProp = new PopupProperty(field, title, item.getDictTable(), item.getDictText(), item.getDictField());
					String backFields = item.getDictText();
					if(backFields!=null && !backFields.equals("")) {
						String[] tempArr = backFields.split(",");
						for (String str : tempArr) {
							if(existFieldName(str, fieldList)) {
								//如果现有的列 有此配置的列 跳过
								continue;
							}
							CommonProperty prop2 = new HiddenProperty(str, str);
							prop2.setOrder(item.getOrderNum());
							props.add(prop2);
						}
					}
					prop = popProp;
				}else if(SELECT_SEARCH.equals(filedShowType)){
					prop = new DictProperty(field, title,  item.getDictTable(), item.getDictField(), item.getDictText());
				}else if(LINK_DOWN.equals(filedShowType)){
					LinkDownProperty linkProp = new LinkDownProperty(field, title,item.getDictTable());
					getLinkDownOtherField(linkProp,fieldList,excludeFields);
					prop = linkProp;
				}else if(SEL_TREE.equals(filedShowType)){
					//树控件
					String dictText = item.getDictText();
					String[] cols = dictText.split(",");
					String dict = item.getDictTable()+","+cols[2]+","+cols[0];
					TreeSelectProperty treeProp = new TreeSelectProperty(field, title, dict, cols[1], item.getDictField());
					if(cols.length>3) {
						treeProp.setHasChildField(cols[3]);
					}
					prop = treeProp;
				}else if(CAT_TREE.equals(filedShowType)){
					//update-begin-author:taoyan 分类字典配置编码 这块支持无配置加载所有
					String dictText = item.getDictText();
					String dictCode = item.getDictField();
					String pid = "0";
					if(oConvertUtils.isNotEmpty(dictCode) && !"0".equals(dictCode)){
						pid = mapper.queryCategoryIdByCode(dictCode);
					}
					if(oConvertUtils.isEmpty(dictText)){
						//分类字典树控件 简易版 只有一个字段
						prop = new TreeSelectProperty(field, title,pid);
					}else{
						//需要处理两个字段
						prop = new TreeSelectProperty(field, title,pid,dictText);
						CommonProperty prop2 = new HiddenProperty(dictText, dictText);
						props.add(prop2);
					}
					//update-end-author:taoyan 分类字典配置编码 这块支持无配置加载所有
				}else {
					if(treeColumn!=null && field.equals(treeColumn.getFieldName())) {
						//树形列表 表单的树控件
						String dict = treeColumn.getTableName()+","+treeColumn.getTextField()+","+treeColumn.getCodeField();
						TreeSelectProperty treeProp = new TreeSelectProperty(field, title, dict, treeColumn.getPidField(), treeColumn.getPidValue());
						treeProp.setHasChildField(treeColumn.getHsaChildField());
						treeProp.setPidComponent(1);
						prop = treeProp;
					}else {
						StringProperty stringProp = new StringProperty(field, title, filedShowType, item.getDbLength());
						// 主表/单表 表单校验 通过pattern实现
						if(oConvertUtils.isNotEmpty(item.getFieldValidType())) {
							CgformValidPatternEnum patternInfo = CgformValidPatternEnum.getPatternInfoByType(item.getFieldValidType());
							if(patternInfo!=null) {
								if(CgformValidPatternEnum.NOTNULL==patternInfo) {
									required.add(field);
								}else {
									stringProp.setPattern(patternInfo.getPattern());
									stringProp.setErrorInfo(patternInfo.getMsg());
								}
                            } else {
                                // update-begin-author:sunjianlei date:20200409 for: 不是预设的正则，就视为用户自定义的正则 --------------
                                stringProp.setPattern(item.getFieldValidType());
                                stringProp.setErrorInfo("输入的值不合法");
                                // update-end-author:sunjianlei date:20200409 for: 不是预设的正则，就视为用户自定义的正则 --------------
                            }
						}
						prop = stringProp;
					}
				}
			}
            // update-begin-author:sunjianlei date:20200221 for: 设置只读字段不可编辑
            if ((item.getIsReadOnly() == 1) || (disabledFieldNameList != null && disabledFieldNameList.indexOf(field) >= 0)) {
                prop.setDisabled(true);
            }
            // update-end-author:sunjianlei date:20200221 for: 设置只读字段不可编辑
			prop.setOrder(item.getOrderNum());
            prop.setDefVal(item.getFieldDefaultValue());
			props.add(prop);
		}
		if(required.size()>0) {
			JsonSchemaDescrip descrip = new JsonSchemaDescrip(required);
			json = JsonschemaUtil.getJsonSchema(descrip, props);
		}else {
			JsonSchemaDescrip descrip = new JsonSchemaDescrip();
			json = JsonschemaUtil.getJsonSchema(descrip, props);
		}
		return json;
	}

	/**
	 * 根据字段集合组装JSON schema 主从表结构从表用到
	 * @param entityDescrib
	 * @param fieldList
	 * @return
	 */
	public static JSONObject getSubJsonSchemaByCgformFieldList(String entityDescrib,List<OnlCgformField> fieldList) {
		JSONObject json = new JSONObject();
		List<String> required = new ArrayList<String>();
		List<CommonProperty> props = new ArrayList<CommonProperty>();
		ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
		for (OnlCgformField item : fieldList) {
			String field = item.getDbFieldName();
			if(P_KEY.equals(field)) {
				continue;
			}
			String title = item.getDbFieldTxt();
			//获取required
			if(YES.equals(item.getFieldMustInput())) {
				required.add(field);
			}
			String filedShowType = item.getFieldShowType();

			//TODO 此处只处理数据字典 没处理字典表
			String dictCode = item.getDictField();
			CommonProperty prop = null;
			if(OnlineDbHandler.isNumField(item.getDbType())) {
				prop = new NumberProperty(field, title, "number");
			}else {
				if(hasDictConfig(filedShowType)) {
					List<DictModel> include = sysBaseAPI.queryDictItemsByCode(dictCode);
					prop = new StringProperty(field, title, filedShowType, item.getDbLength(), include);
				}else {
					prop = new StringProperty(field, title, filedShowType, item.getDbLength());
				}
			}
			prop.setOrder(item.getOrderNum());
			props.add(prop);
		}
		json = JsonschemaUtil.getSubJsonSchema(entityDescrib, required, props);
		return json;
	}

	/**
	  *  获取必须要处理的列 POPUP回调的列但是该列隐藏
	 * @return
	 */
	public static Set<String> getNeedhandleField(List<OnlCgformField> fieldList){
		Set<String> set = new HashSet<String>();
		for (OnlCgformField item : fieldList) {
			if(POPUP.equals(item.getFieldShowType())) {
				String dictText = item.getDictText();
				if(dictText!=null && !dictText.equals("")) {
					set.addAll(Arrays.stream(dictText.split(",")).collect(Collectors.toSet()));
				}
			}
			if(CAT_TREE.equals(item.getFieldShowType())) {
				String dictText = item.getDictText();
				if(oConvertUtils.isNotEmpty(dictText)){
					set.add(dictText);
				}
			}
		}
		for (OnlCgformField item : fieldList) {
			String key = item.getDbFieldName();
			if(item.getIsShowForm()==1 && set.contains(key)) {
				//如果字段是显示的就没必要在这里处理了
				set.remove(key);
			}
		}
		return set;
	}

	/**
	 * 表单数据保存SQL获取 默认id是主键并且为uuid
	 * @param fieldList 所有的列
	 * @throws DBException
	 * @throws SQLException
	 */
	public static Map<String,Object> getFormDataSaveSql(String tbname,List<OnlCgformField> fieldList,JSONObject json) {
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		String dataBase="";
		try {
			dataBase = DbTableUtil.getDatabaseType();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (DBException e) {
			e.printStackTrace();
		}
		Map<String,Object> params = new HashMap<String,Object>();
		boolean hasKey = false;
		String keyFieldValue=null;
		LoginUser sysUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if (sysUser == null) {
			throw new JeecgBootException("online保存表单数据异常:系统未找到当前登陆用户信息");
		}

		//必要字段获取
		Set<String> needFields = getNeedhandleField(fieldList);

		//注意 ：此处循环内部代码 会改变原始集合中对象的属性值 如果持久层是hibernate需要手动new 一个新的
		for (OnlCgformField item : fieldList) {
			String key = item.getDbFieldName();
			if(null==key) {
				log.info("--------online保存表单数据遇见空名称的字段------->>"+item.getId());
				continue;
			}

			if(P_KEY.equals(key.toLowerCase())) {
				hasKey = true;
				keyFieldValue = json.getString(key);
				continue;
			}

			//赋值系统默认字段
			initSystemFileds(item, sysUser, json,CREATE_BY,CREATE_TIME,SYS_ORG_CODE);

			//设置流程状态的默认值 1：待提交
			if(BPM_STATUS.equals(key.toLowerCase())){
				sb1.append(SQL_COMMA+key);
				sb2.append(SQL_COMMA+SQL_SQ+1+SQL_SQ);
				continue;
			}

			//处理必要字段
			if(needFields.contains(key)) {
				//拼接insert into (这里面的东西)
				sb1.append(SQL_COMMA+key);
				//拼接insert into (...) values (这里面的东西)
				String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
				sb2.append(SQL_COMMA+sqlValue);
				continue;
			}

			//不显示且非外键不入库 且数据库没有设置默认值
			if(item.getIsShowForm()!=1 && oConvertUtils.isEmpty(item.getMainField()) && !"has_child".equals(item.getDbFieldName())&&
					!"prows".equals(item.getDbFieldName())) {
				if(oConvertUtils.isEmpty(item.getDbDefaultVal())){
					continue;
				}
			}

			//为空不入库 如果有默认值则设置默认值
			if(json.get(key)==null) {
				if(oConvertUtils.isEmpty(item.getDbDefaultVal())){
					continue;
				}else{
					json.put(key,item.getDbDefaultVal());
				}
			}

			//数值/时间类型 值为空不改
			if("".equals(json.get(key))) {
				String dbType = item.getDbType();
				if(OnlineDbHandler.isNumField(dbType) || OnlineDbHandler.isDateField(dbType)) {
					continue;
				}
			}

			//拼接insert into (这里面的东西)
			sb1.append(SQL_COMMA+key);

			//拼接insert into (...) values (这里面的东西)
			String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
			sb2.append(SQL_COMMA+sqlValue);
		}

		if(hasKey) {
			if(oConvertUtils.isEmpty(keyFieldValue)) {
				keyFieldValue = CgformUtil.randomId();
			}
		}else {
			keyFieldValue =  CgformUtil.randomId();
		}
		String sql = "insert into "+getRealTableName(tbname)+"("+P_KEY+sb1.toString()+") values("+SQL_SQ+keyFieldValue+SQL_SQ+sb2.toString()+")";
		params.put("execute_sql_string", sql);
		log.info("--动态表单保存sql-->"+sql);
		return params;
	}


	/**
	 * 表单数据修改SQL获取 默认id是主键并且为uuid
	 */
	public static Map<String,Object> getFormDataEditSql(String tbname,List<OnlCgformField> fieldList,JSONObject json) {
		StringBuffer sb = new StringBuffer();
		Map<String,Object> params = new HashMap<String,Object>();
		String dataBase="";
		try {
			dataBase = DbTableUtil.getDatabaseType();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (DBException e) {
			e.printStackTrace();
		}

		LoginUser sysUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if (sysUser == null) {
			throw new JeecgBootException("online修改表单数据异常:系统未找到当前登陆用户信息");
		}

		//获取必要字段
		Set<String> needFields = getNeedhandleField(fieldList);

		//注意 暂时只能修改界面上显示的数据
		for (OnlCgformField item : fieldList) {
			String key = item.getDbFieldName();
			if(null==key) {
				log.info("--------online修改表单数据遇见空名称的字段------->>"+item.getId());
				continue;
			}

			//赋值系统默认字段
			initSystemFileds(item, sysUser, json,UPDATE_BY,UPDATE_TIME,SYS_ORG_CODE);

			//处理必要字段
			if(needFields.contains(key)) {
				//拼接insert into (这里面的东西)
				if(json.get(key)!=null && !"".equals(json.getString(key))) {
					String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
					sb.append(key+SQL_EQ+sqlValue+SQL_COMMA);
					continue;
				}
			}

			//不显示不改
			if(item.getIsShowForm()!=1) {
				continue;
			}
			//主键不改
			if(P_KEY.equals(key)) {
				continue;
			}
			//数值/时间类型 值为空不改
			if("".equals(json.get(key))) {
				String dbType = item.getDbType();
				if(OnlineDbHandler.isNumField(dbType)||OnlineDbHandler.isDateField(dbType)) {
					continue;
				}
			}

			String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
			sb.append(key+SQL_EQ+sqlValue+SQL_COMMA);

		}

		String condition = sb.toString();
		if(condition.endsWith(SQL_COMMA)) {
			condition = condition.substring(0,condition.length()-1);
		}
		String sql = "update "+getRealTableName(tbname)+" set "+condition+ SQL_WHERE_TRUE +SQL_AND + P_KEY + SQL_EQ +SQL_SQ+json.getString(P_KEY)+SQL_SQ;
		log.info("--动态表单编辑sql-->"+sql);
		params.put("execute_sql_string", sql);
		return params;
	}

	/**
	 * 获取根据id查询的sql
	 * @param tbname
	 * @param fieldList
	 * @return
	 */
	public static String getSelectFormSql(String tbname,List<OnlCgformField> fieldList,String id) {
		return getSelectSubFormSql(tbname, fieldList, P_KEY, id);
	}

	/**
	 * 组装查询SQL
	 * @param tbname 表名
	 * @param fieldList 需要查询的字段集合
	 * @param linkField 查询条件字段
	 * @param value 查询条件值
	 * @return
	 */
	public static String getSelectSubFormSql(String tbname,List<OnlCgformField> fieldList,String linkField,String value) {
		StringBuffer sb = new StringBuffer();
		//TODO  这边暂时将id也返回给前端了
		sb.append(SQL_SELECT);
		int size = fieldList.size();
		boolean has = false;
		for(int i=0;i<size;i++) {
			String key = fieldList.get(i).getDbFieldName();
			if(P_KEY.equals(key)) {
				has = true;
			}
			sb.append(key);
			if(size>i+1) {
				sb.append(SQL_COMMA);
			}
		}
		if(!has) {
			sb.append(SQL_COMMA+P_KEY);
		}
		sb.append(SQL_FROM+getRealTableName(tbname)+SQL_WHERE_TRUE + SQL_AND + linkField + SQL_EQ+"'"+value+"'");
		return sb.toString();
	}

	/**
	 * 给系统变量赋值
	 * @param json
	 */
	public static void initSystemFileds(OnlCgformField item,LoginUser sysUser,JSONObject json,String... systemFields) {
		//1.判断系统字段是否显示于前端 不显示前端 则设定默认值
		//2.如果显示那么 判断json数据中是否有数据 没有数据则设定默认值
		String key = item.getDbFieldName();
		boolean need = false;
		for (String field : systemFields) {
			if(key.toUpperCase().equals(field)) {
				if(item.getIsShowForm()==1) {
					if(json.get(key)==null) {
						need = true;
					}
				}else {
					item.setIsShowForm(1);
					need = true;
				}
				if(need) {
					switch (field) {
					case CREATE_BY:
						json.put(key, sysUser.getUsername());
						break;
					case CREATE_TIME:
						item.setFieldShowType("datetime");
						json.put(key, DateUtils.formatDateTime());
						break;
					case UPDATE_BY:
						json.put(key, sysUser.getUsername());
						break;
					case UPDATE_TIME:
						item.setFieldShowType("datetime");
						json.put(key, DateUtils.formatDateTime());
						break;
					case SYS_ORG_CODE:
						json.put(key, sysUser.getOrgCode());
						break;
					default:
						break;
					}
				}
				break;
			}

		}
	}

	/**
	 * 比较两个是否相等
	 * @param oldvalue
	 * @param newvalue
	 * @return
	 */
	public static boolean compareValue(Object oldvalue,Object newvalue){
		if(oConvertUtils.isEmpty(oldvalue) && oConvertUtils.isEmpty(newvalue)) {
			return true;
		}else {
			if(oConvertUtils.isNotEmpty(oldvalue) && oldvalue.equals(newvalue)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 通过比较OnlCgformField配置信息判断数据库表信息是否变动
	 * @param oldColumn
	 * @param newColumn
	 * @return
	 */
	public static boolean databaseFieldIsChange(OnlCgformField oldColumn,OnlCgformField newColumn) {
		if (!compareValue(oldColumn.getDbFieldName(), newColumn.getDbFieldName())
				|| !compareValue(oldColumn.getDbFieldTxt(),newColumn.getDbFieldTxt())
				|| !compareValue(oldColumn.getDbLength(),newColumn.getDbLength())
				|| !compareValue(oldColumn.getDbPointLength(),newColumn.getDbPointLength())
				|| !compareValue(oldColumn.getDbType(),newColumn.getDbType())
				|| !compareValue(oldColumn.getDbIsNull(),newColumn.getDbIsNull())
				//|| !compareValue(oldColumn.getOrderNum(),newColumn.getOrderNum())
				|| !compareValue(oldColumn.getDbIsKey(),newColumn.getDbIsKey())
				//update-begin-author:taoyan date:20191008 for:TASK #3241 8配置外键，不需要同步数据库
				//|| !compareValue(oldColumn.getMainTable(),newColumn.getMainTable())
				//|| !compareValue(oldColumn.getMainField(),newColumn.getMainField())
				//update-end-author:taoyan date:20191008 for:TASK #3241 8配置外键，不需要同步数据库
				||!compareValue(oldColumn.getDbDefaultVal(),newColumn.getDbDefaultVal())) {
			return true;
		}
		return false;
	}

	/**
	 * 判断数据库索引是否改变
	 * @param oldIndex
	 * @param newIndex
	 * @return
	 */
	public static boolean databaseIndexIsChange(OnlCgformIndex oldIndex,OnlCgformIndex newIndex) {
		if (!compareValue(oldIndex.getIndexName(), newIndex.getIndexName())
				|| !compareValue(oldIndex.getIndexField(),newIndex.getIndexField())
				|| !compareValue(oldIndex.getIndexType(),newIndex.getIndexType())) {
			return true;
		}
		return false;
	}

	/**
	 * 判断数据库表是否改变
	 * @param oldTable
	 * @param newTable
	 * @return
	 */
	public static boolean databaseTableIsChange(OnlCgformHead oldTable,OnlCgformHead newTable) {
		if (!compareValue(oldTable.getTableName(), newTable.getTableName()) || !compareValue(oldTable.getTableTxt(), newTable.getTableTxt())) {
			return true;
		}
		return false;
	}

	/**
	 * 获取查询列表的条件SQL
	 * @param fieldList
	 * @param params
	 * @return
	 */
	public static String getQueryListDataCondition(String tbname,List<OnlCgformField> fieldList,Map<String, Object> params) {
		StringBuffer sb = new StringBuffer();
		StringBuffer selectField = new StringBuffer();
		for (OnlCgformField item : fieldList) {
			String field = item.getDbFieldName();
			String dbtype = item.getDbType();
			if(item.getIsShowList()==1) {
				selectField.append(SQL_COMMA+field);
			}

			//对于外键字段添加逻辑处理
			if(oConvertUtils.isNotEmpty(item.getMainField())) {
				boolean isString = !OnlineDbHandler.isNumField(dbtype);
				String fieldCondition = QueryGenerator.getSingleQueryConditionSql(field, "", params.get(field), isString);
				if(!"".equals(fieldCondition)) {
					sb.append(SQL_AND+fieldCondition);
				}

			}

			if(item.getIsQuery()==1) {
				if(QUERY_MODE_SINGLE.equals(item.getQueryMode())) {
					//单条件查询
					if(params.get(field)==null) {
						continue;
					}
					boolean isString = !OnlineDbHandler.isNumField(dbtype);
					String fieldCondition = QueryGenerator.getSingleQueryConditionSql(field, "", params.get(field), isString);
					if("".equals(fieldCondition)) {
						continue;
					}
					sb.append(SQL_AND+fieldCondition);
				}else {
					Object beginVal = params.get(field+"_begin");
					if(beginVal!=null) {
						sb.append(SQL_AND+field+SQL_GE);
						if(OnlineDbHandler.isNumField(dbtype)) {
							sb.append(beginVal.toString());
						}else{
							sb.append(SQL_SQ+beginVal.toString()+SQL_SQ);
						}
					}
					Object endVal = params.get(field+"_end");
					if(endVal!=null) {
						sb.append(SQL_AND+field+SQL_LE);
						if(OnlineDbHandler.isNumField(dbtype)) {
							sb.append(endVal.toString());
						}else{
							sb.append(SQL_SQ+endVal.toString()+SQL_SQ);
						}
					}

				}
			}
		}
		return SQL_SELECT+P_KEY+selectField.toString()+SQL_FROM+getRealTableName(tbname)+SQL_WHERE_TRUE+sb.toString();
	}

	/**
	  * 把基础数据转换成Excel导出的数据
	 * @param lists 列集合
	 * @param pkField 如果pkField为null 则不过滤主键
	 * @return
	 */
	public static List<ExcelExportEntity> convertToExportEntity(List<OnlCgformField> lists,String pkField) {
		List<ExcelExportEntity> entityList = new ArrayList<ExcelExportEntity>();
		for (int i = 0; i < lists.size(); i++) {
			if(null!=pkField && pkField.equals(lists.get(i).getDbFieldName())) {
				continue;
			}
			if (lists.get(i).getIsShowList()==1) {
				ExcelExportEntity entity = new ExcelExportEntity(lists.get(i).getDbFieldTxt(), lists.get(i).getDbFieldName());
				int columnWidth = lists.get(i).getDbLength() == 0 ? 12 : lists.get(i).getDbLength() > 30 ? 30 : lists.get(i).getDbLength();
				if (lists.get(i).getFieldShowType().equals("date")) {
					entity.setFormat("yyyy-MM-dd");
				} else if (lists.get(i).getFieldShowType().equals("datetime")) {
					entity.setFormat("yyyy-MM-dd HH:mm:ss");
				}
				if(columnWidth<10){
					columnWidth = 10;
				}
				entity.setWidth(columnWidth);
				entityList.add(entity);
			}
		}
		return entityList;
	}

	/**
	 * 判断class或是spring的bean是否存在
	 * @param onlCgformEnhanceJava
	 * @return
	 */
	public static boolean checkClassOrSpringBeanIsExist(OnlCgformEnhanceJava onlCgformEnhanceJava) {
		String cgJavaType = onlCgformEnhanceJava.getCgJavaType();
		String cgJavaValue = onlCgformEnhanceJava.getCgJavaValue();
		if(oConvertUtils.isNotEmpty(cgJavaValue)){
			try {
				if("class".equals(cgJavaType)){
					Class clazz = Class.forName(cgJavaValue);
					if(clazz==null || clazz.newInstance()==null) {
						return false;
					}
				}

				if("spring".equals(cgJavaType)){
					Object obj = SpringContextUtils.getBean(cgJavaValue);
					if(obj==null) {
						return false;
					}
				}
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				return false;
			}
		}
		return true;
	}

	/**
	 * 字符串集合排序 不比较长度
	 * @param list
	 */
	public static void sortStringList(List<String> list) {
		Collections.sort(list, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				if(o1 == null || o2 == null){
		            return -1;
		        }
		        if(o1.compareTo(o2) > 0){
		            return 1;
		        }
		        if(o1.compareTo(o2) < 0){
		            return -1;
		        }
		        if(o1.compareTo(o2) == 0){
		            return 0;
		        }
		        return 0;
			}
		});
	}

	/**
	 * 字符串集合排序 优先比较长度
	 * @param list
	 */
	public static void sortStringList2(List<String> list) {
		Collections.sort(list, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				if(o1 == null || o2 == null){
		            return -1;
		        }
		        if(o1.length() > o2.length()){
		            return 1;
		        }
		        if(o1.length() < o2.length()){
		            return -1;
		        }
		        if(o1.compareTo(o2) > 0){
		            return 1;
		        }
		        if(o1.compareTo(o2) < 0){
		            return -1;
		        }
		        if(o1.compareTo(o2) == 0){
		            return 0;
		        }
		        return 0;
			}
		});
	}

	/**
	 * 转化数据规则配置的系统变量
	 * @param value
	 * @param flag
	 * @return
	 */
	private static String converRuleValue(String value,boolean flag) {
		if(flag) {
			return SQL_SQ+QueryGenerator.converRuleValue(value)+SQL_SQ;
		}else {
			return QueryGenerator.converRuleValue(value);
		}
	}

	/**
	 * 根据数据规则对象 组装SQL
	 * @param dataBase 数据库类型
	 * @param dataRule 数据规则
	 * @param field 字段名
	 * @param dbtype 字段类型
	 * @param sb sql拼接对象
	 */
	private static void addRuleToStringBuffer(String dataBase,SysPermissionDataRuleModel dataRule, String field, String dbtype, StringBuffer sb) {
		QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
		boolean isSq = !OnlineDbHandler.isNumField(dbtype);
		String value = converRuleValue(dataRule.getRuleValue(),isSq);
		if (value == null || rule == null) {
			return;
		}

		//针对 oracle数据库，时间值特殊处理
		if (DataBaseConstant.DB_TYPE_ORACLE.equalsIgnoreCase(dataBase)) {
			if ("Date".equals(dbtype)) {
				value = value.replace("'","");
				if (value.length() == 10) {
					value = getOracletoDateString(value);
				} else {
					value = getOracletoDateTimeString(value);
				}
			}
		}

		switch (rule) {
		case GT:
			sb.append(SQL_AND+field+SQL_GT+value);
			break;
		case GE:
			sb.append(SQL_AND+field+SQL_GE+value);
			break;
		case LT:
			sb.append(SQL_AND+field+SQL_LT+value);
			break;
		case LE:
			sb.append(SQL_AND+field+SQL_LE+value);
			break;
		case EQ:
			sb.append(SQL_AND+field+SQL_EQ+value);
			break;
		case NE:
			sb.append(SQL_AND+field+" <> "+value);
			break;
		case IN:
			sb.append(SQL_AND+field+" IN "+value);
			break;
		case LIKE:
			sb.append(SQL_AND+field+" LIKE '%"+QueryGenerator.trimSingleQuote(value)+"%'");
			break;
		case LEFT_LIKE:
			sb.append(SQL_AND+field+" LIKE '%"+QueryGenerator.trimSingleQuote(value)+"'");
			break;
		case RIGHT_LIKE:
			sb.append(SQL_AND+field+" LIKE '"+QueryGenerator.trimSingleQuote(value)+"%'");
			break;
		default:
			log.info("--查询规则未匹配到---");
			break;
		}
	}


	/**
	 * sql值替换 SQL增强用于替换sql中的变量用
	 * @param sql
	 * @param json
	 * @return
	 */
	public static String formateSQl(String sql, JSONObject json) {
		if (json == null) {
			return sql;
		}
		sql = sql.replace("#{UUID}", UUIDGenerator.generate());
		Set<String> varParams = QueryGenerator.getSqlRuleParams(sql);

		for(String key:varParams){
			if(json.get(key.toUpperCase())==null && json.get(key.toLowerCase())==null) {
				String tempValue = QueryGenerator.converRuleValue(key);
				sql = sql.replace("#{" + key + "}",tempValue);
			}else {
				String jsonValue = null;
				if(json.containsKey(key.toLowerCase())){
					jsonValue = json.getString(key.toLowerCase());
				}else if(json.containsKey(key.toUpperCase())){
					jsonValue = json.getString(key.toUpperCase());
				}
				sql = sql.replace("#{" + key + "}",jsonValue);
			}
		}
		return sql;
	}

	/**
	 * 将原js字符串重新包装一下
	 * 如果是link类型的按钮支持带一个参数row
	 * @param enhanceJs
	 * @return
	 */
	private static final String enhanceJsButtonCode = "beforeAdd,beforeEdit,afterAdd,afterEdit,beforeDelete,afterDelete,mounted,created";
	public static String overwriteJs(String enhanceJs,List<OnlCgformButton> cgButtonList) {
		enhanceJs = overwriteJsByButtonStyle(enhanceJs, cgButtonList);
		for (String temp : enhanceJsButtonCode.split(",")) {
			if("beforeAdd,afterAdd,mounted,created".indexOf(temp)>=0) {
				Pattern p = Pattern.compile("("+temp+"\\s*\\(\\)\\s*\\{)");
				Matcher m = p.matcher(enhanceJs);
				if(m.find()) {
					enhanceJs = enhanceJs.replace(m.group(0), temp+"(that){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
				}
			}else {
				Pattern p = Pattern.compile("("+temp+"\\s*\\(row\\)\\s*\\{)");
				Matcher m = p.matcher(enhanceJs);
				if(m.find()) {
					enhanceJs = enhanceJs.replace(m.group(0), temp+"(that,row){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
				}else {
					Pattern p2 = Pattern.compile("("+temp+"\\s*\\(\\)\\s*\\{)");
					Matcher m2 = p2.matcher(enhanceJs);
					if(m2.find()) {
						enhanceJs = enhanceJs.replace(m2.group(0), temp+"(that){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
					}
				}
			}
		}
		return returnEnhanceJsClass(enhanceJs);

	}

	/**
	 * form页面的js 增强
	 * @param enhanceJs
	 * @return
	 */
	public static void overwriteJs(OnlCgformEnhanceJs onlCgformEnhanceJs,String tbname,List<OnlCgformField> fieldList) {
		if(onlCgformEnhanceJs==null || oConvertUtils.isEmpty(onlCgformEnhanceJs.getCgJs())) {
			return;
		}
		String enhanceJs = onlCgformEnhanceJs.getCgJs();
		String onlChange = "onlChange";
		Pattern p = Pattern.compile("("+tbname+"_"+onlChange+"\\s*\\(\\)\\s*\\{)");
		Matcher m = p.matcher(enhanceJs);
		if(m.find()) {
			enhanceJs = enhanceJs.replace(m.group(0), tbname+"_"+onlChange+"(){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
			for (OnlCgformField field : fieldList) {
				Pattern p1 = Pattern.compile("("+field.getDbFieldName()+"\\s*\\(\\))");
				Matcher m1 = p1.matcher(enhanceJs);
				if(m1.find()) {
					enhanceJs = enhanceJs.replace(m1.group(0), field.getDbFieldName()+"(that,event)");
				}
			}
		}
		onlCgformEnhanceJs.setCgJs(enhanceJs);
	}

	/**
	 * 主表增强JS表单change事件不用带上主表名(tablename_onlChange)可以直接是onlChange
	 * @param onlCgformEnhanceJs
	 * @param tbname
	 * @param fieldList
	 * @param isMain
	 */
	public static void overwriteJs(OnlCgformEnhanceJs onlCgformEnhanceJs,String tbname,List<OnlCgformField> fieldList,boolean isMain) {
		if(onlCgformEnhanceJs==null || oConvertUtils.isEmpty(onlCgformEnhanceJs.getCgJs())) {
			return;
		}
		String enhanceJs = onlCgformEnhanceJs.getCgJs();
		String onlChange = "onlChange";
		Pattern p = Pattern.compile("([^_]"+onlChange+"\\s*\\(\\)\\s*\\{)");
		Matcher m = p.matcher(enhanceJs);
		if(m.find()) {
			enhanceJs = enhanceJs.replace(m.group(0), onlChange+"(){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
			for (OnlCgformField field : fieldList) {
				Pattern p1 = Pattern.compile("("+field.getDbFieldName()+"\\s*\\(\\))");
				Matcher m1 = p1.matcher(enhanceJs);
				if(m1.find()) {
					enhanceJs = enhanceJs.replace(m1.group(0), field.getDbFieldName()+"(that,event)");
				}
			}
		}
		onlCgformEnhanceJs.setCgJs(enhanceJs);
		replaceShowMethod(onlCgformEnhanceJs);
		overwriteJs(onlCgformEnhanceJs, tbname, fieldList);
	}

	public static void replaceShowMethod(OnlCgformEnhanceJs onlCgformEnhanceJs){
		String enhanceJs = onlCgformEnhanceJs.getCgJs();
		String temp = "show";
		Pattern p = Pattern.compile("("+temp+"\\s*\\(\\)\\s*\\{)");
		Matcher m = p.matcher(enhanceJs);
		if(m.find()) {
			enhanceJs = enhanceJs.replace(m.group(0), temp+"(that){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
		}
		onlCgformEnhanceJs.setCgJs(enhanceJs);
	}


	/**
	  * 在enhanceJS外面套一层class对象
	 * @param enhanceJs
	 * @return
	 */
	public static String returnEnhanceJsClass(String enhanceJs) {
		log.info("最终的增强JS",enhanceJs);
		return "class OnlineEnhanceJs{constructor(getAction,postAction,deleteAction){this._getAction=getAction;this._postAction=postAction;this._deleteAction=deleteAction;}"+enhanceJs+"}";
	}

	/**
	  * 根据按钮类型内置方法参数
	 * @param enhanceJs
	 * @param cgButtonList
	 * @return
	 */
	public static String overwriteJsByButtonStyle(String enhanceJs,List<OnlCgformButton> cgButtonList) {
		if(cgButtonList!=null) {
			for (OnlCgformButton button : cgButtonList) {
				String temp = button.getButtonCode();
				if("link".equals(button.getButtonStyle())) {
					Pattern p = Pattern.compile("("+temp+"\\s*\\(row\\)\\s*\\{)");
					Matcher m = p.matcher(enhanceJs);
					if(m.find()) {
						enhanceJs = enhanceJs.replace(m.group(0), temp+"(that,row){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
					}else {
						Pattern p2 = Pattern.compile("("+temp+"\\s*\\(\\)\\s*\\{)");
						Matcher m2 = p2.matcher(enhanceJs);
						if(m2.find()) {
							enhanceJs = enhanceJs.replace(m2.group(0), temp+"(that){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
						}
					}
				}else if("button".equals(button.getButtonStyle()) || "form".equals(button.getButtonStyle())) {
					Pattern p = Pattern.compile("("+temp+"\\s*\\(\\)\\s*\\{)");
					Matcher m = p.matcher(enhanceJs);
					if(m.find()) {
						enhanceJs = enhanceJs.replace(m.group(0), temp+"(that){const getAction=this._getAction,postAction=this._postAction,deleteAction=this._deleteAction;");
					}
				}
			}
		}
		return enhanceJs;
	}

	/**
	 * 获取JEditableTable列的json数据
	 */
	public static JSONArray getJEditableTableColumnsJson(List<OnlCgformField> fieldList,List<String> disabledList) {
		JSONArray array = new JSONArray();
		ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
		for (OnlCgformField item : fieldList) {
			String field = item.getDbFieldName();
			if(P_KEY.equals(field)) {
				continue;
			}
			JSONObject obj = new JSONObject();
			if(disabledList.indexOf(field)>=0){
                obj.put("disabled", true);
            }
			obj.put("title",item.getDbFieldTxt());
			obj.put("key", field);
			obj.put("width", "186px");
			//update-begin-author:taoyan date:20190827 for:行编辑扩展
			String viewType = getJEditableTableColumnsType(item);
			obj.put("type", viewType);
			if(viewType.equals("file")||viewType.equals("image")) {
				obj.put("responseName", "message");
				obj.put("token", true);
			}
			if(viewType.equals("switch")) {
				obj.put("type", "checkbox");
				JSONArray customValue = new JSONArray();
				if(oConvertUtils.isEmpty(item.getFieldExtendJson())) {
					customValue.add("Y");
					customValue.add("N");
				}else {
					customValue = JSONArray.parseArray(item.getFieldExtendJson());
				}
				obj.put("customValue",customValue);
			}
			if(viewType.equals("popup")) {
				obj.put("popupCode",item.getDictTable());
				obj.put("orgFields",item.getDictField());
				obj.put("destFields",item.getDictText());
				String backFields = item.getDictText();
				if(backFields!=null && !backFields.equals("")) {
					List<String> hiddenFields = new ArrayList<String>();
					String[] tempArr = backFields.split(",");
					for (String str : tempArr) {
						if(existFieldName(str, fieldList)) {
							//如果现有的列 有此配置的列 跳过
							continue;
						}
						hiddenFields.add(str);
						JSONObject obj2 = new JSONObject();
						obj2.put("title",str);
						obj2.put("key", str);
						obj2.put("type", "hidden");
						array.add(obj2);
					}
				}

			}
			//update-end-author:taoyan date:20190827 for:行编辑扩展
			obj.put("defaultValue", item.getDbDefaultVal());
			obj.put("fieldDefaultValue", item.getFieldDefaultValue());
			obj.put("placeholder", "请输入"+item.getDbFieldTxt());
			obj.put("validateRules", getValidateRules(item));

			if("list".equals(item.getFieldShowType())
					||"radio".equals(item.getFieldShowType())
					||"checkbox_meta".equals(item.getFieldShowType())
					||"list_multi".equals(item.getFieldShowType())
					||"sel_search".equals(item.getFieldShowType())) {
				List<DictModel> include = new ArrayList<DictModel>();
				if(oConvertUtils.isNotEmpty(item.getDictTable())) {
					include = sysBaseAPI.queryTableDictItemsByCode(item.getDictTable(), item.getDictText(), item.getDictField());
				}else if(oConvertUtils.isNotEmpty(item.getDictField())) {
					include = sysBaseAPI.queryDictItemsByCode(item.getDictField());
				}
				//TODO
//				for (Map<String,Object> map : include) {
//					map.put("title", map.get("text"));
//				}
				obj.put("options", include);
				if("list_multi".equals(item.getFieldShowType())){
					//多选框设定长度 防止控件变形
					obj.put("width", "230px");
				}
			}
			array.add(obj);
		}
		return array;
	}

	/**
	 * 获取验证信息
	 */
	private static JSONArray getValidateRules(OnlCgformField item) {
		JSONArray array = new JSONArray();
		if(item.getDbIsNull()==0||"1".equals(item.getFieldMustInput())) {
			JSONObject json = new JSONObject();
			json.put("required", true);
			json.put("message", item.getDbFieldTxt()+"不能为空!");
			array.add(json);
		}
		if(oConvertUtils.isNotEmpty(item.getFieldValidType())) {
			JSONObject json2 = new JSONObject();
			if ("only".equals(item.getFieldValidType())) {
				//唯一校验 子表不支持
				json2.put("pattern",null);
			}else{
				json2.put("pattern",item.getFieldValidType());
			}
			json2.put("message", item.getDbFieldTxt()+"格式不正确");
			array.add(json2);
		}
		return array;
	}


	/**
	 * map的key转成小写
	 * @param orgMap
	 * @return
	 */
    public static Map<String, Object> transLowerCaseMapKey(Map<String, Object> orgMap){
        Map<String, Object> resultMap = new HashMap<>();
        if (orgMap == null || orgMap.isEmpty()) {
            return resultMap;
        }
        Set<String> keySet = orgMap.keySet();
        for (String key : keySet) {
            //update-begin--Author:scott  Date:20190926 for：TASK #3210 【数据库兼容bug】oracle下大字段报错------------------
            //clob字段处理
            Object val = orgMap.get(key);
            if (val instanceof Clob) {
                val = Clob2String((Clob) val);
            }else if(val instanceof byte[]){
				val = new String((byte[])val);
            }else if (val instanceof Blob) {
                try {
                    if (val != null) {
                        Blob val_b = (Blob) val;
                        val = new String(val_b.getBytes(1, (int) val_b.length()), "UTF-8");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            String newKey = key.toLowerCase();
            resultMap.put(newKey, val);
            //update-end--Author:scott  Date:20190926 for：TASK #3210 【数据库兼容bug】oracle下大字段报错------------------
        }
        return resultMap;
    }

	/**
	 * 将json key转成小写
	 * @param json
	 * @return
	 */
	public static JSONObject transLowerCaseMapKey(JSONObject json){
		if(DbTableUtil.hasLetterCaseProblem()){
			JSONObject resultJson = new JSONObject();
			if (json == null || json.isEmpty()) {
				return resultJson;
			}
			Set<String> keySet = json.keySet();
			for (String key : keySet) {
				String newKey = key.toLowerCase();
				resultJson.put(newKey, json.get(key));
			}
			return resultJson;
		}else{
			return json;
		}
	}


    /**
	 * 转小写
	 * @param list
	 * @return
	 */
	public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){
		List<Map<String, Object>> select = new ArrayList<>();
		for (Map<String, Object> row : list) {
			 Map<String, Object> resultMap = new HashMap<>();
			 Set<String> keySet = row.keySet();
			 for (String key : keySet) {
                 //update-begin--Author:scott  Date:20190926 for：TASK #3210 【数据库兼容bug】oracle下大字段报错------------------
                 //clob字段处理
                 Object val = row.get(key);
                 if (val instanceof Clob) {
                     val = Clob2String((Clob) val);
				 } else if (val instanceof byte[]) {
					 val = new String((byte[]) val);
				 } else if (val instanceof Blob) {
					 try {
						 if (val != null) {
							 Blob val_b = (Blob) val;
							 val = new String(val_b.getBytes(1, (int) val_b.length()), "UTF-8");
						 }
					 } catch (Exception e) {
						 e.printStackTrace();
					 }
				 }
                 String newKey = key.toLowerCase();
                 resultMap.put(newKey, val);
                 //update-end--Author:scott  Date:20190926 for：TASK #3210 【数据库兼容bug】oracle下大字段报错------------------
			 }
			 select.add(resultMap);
		}
		return select;
	}

    /**
     * Clob字段转String
     * @param clob
     * @return
     */
    public static String Clob2String(Clob clob) {
        String clobStr = "";
        try {
            Reader inStream = clob.getCharacterStream();
            char[] c = new char[(int) clob.length()];
            inStream.read(c);
            clobStr = new String(c);
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return clobStr;
    }

	/**
	 * 表单设计器获取动态sql用于保存表单数据
	 * @throws DBException
	 * @throws SQLException
	 */
	public static Map<String,Object> getCrazyFormDataSaveSql(String tbname,List<OnlCgformField> fieldList,JSONObject json) {
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		String dataBase="";
		try {
			dataBase = DbTableUtil.getDatabaseType();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (DBException e) {
			e.printStackTrace();
		}
		Map<String,Object> params = new HashMap<String,Object>();
		boolean hasKey = false;
		String keyFieldValue = null;

		LoginUser sysUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if (sysUser == null) {
			throw new JeecgBootException("online保存表单数据异常:系统未找到当前登陆用户信息");
		}

		for (OnlCgformField item : fieldList) {
			String key = item.getDbFieldName();
			if(null==key) {
				log.info("--------online保存表单数据遇见空名称的字段------->>"+item.getId());
				continue;
			}
			//为空且不为标准字段则不入库
			if (json.get(key) == null && !(CREATE_BY.equalsIgnoreCase(key) || CREATE_TIME.equalsIgnoreCase(key) || SYS_ORG_CODE.equalsIgnoreCase(key))) {
				continue;
			}

			//赋值系统默认字段
			initSystemFileds(item, sysUser, json, CREATE_BY, CREATE_TIME, SYS_ORG_CODE);

			//数值/时间类型 值为空不改
			if("".equals(json.get(key))) {
				String dbType = item.getDbType();
				if(OnlineDbHandler.isNumField(dbType)||OnlineDbHandler.isDateField(dbType)) {
					continue;
				}
			}
			if(P_KEY.equals(key.toLowerCase())) {
				hasKey = true;
				keyFieldValue = json.getString(key);
				continue;
			}
			//拼接insert into (这里面的东西)
			sb1.append(SQL_COMMA+key);
			//拼接insert into (...) values (这里面的东西)
			String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
			sb2.append(SQL_COMMA+sqlValue);
		}
		if(!hasKey || oConvertUtils.isEmpty(keyFieldValue)) {
			keyFieldValue = CgformUtil.randomId();
		}
		String sql = "insert into "+getRealTableName(tbname)+"("+P_KEY+sb1.toString()+") values("+SQL_SQ+keyFieldValue+SQL_SQ+sb2.toString()+")";
		params.put("execute_sql_string", sql);
		log.info("--表单设计器表单保存sql-->"+sql);
		return params;
	}

	/**
	 * 表单设计器获取动态sql用于编辑表单数据
	 * @param tbname
	 * @param fieldList
	 * @param json
	 * @return
	 */
	public static Map<String,Object> getCrazyFormDataEditSql(String tbname,List<OnlCgformField> fieldList,JSONObject json) {
		StringBuffer sb = new StringBuffer();
		Map<String,Object> params = new HashMap<String,Object>();
		String dataBase="";
		try {
			dataBase = DbTableUtil.getDatabaseType();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (DBException e) {
			e.printStackTrace();
		}
		LoginUser sysUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if (sysUser == null) {
			throw new JeecgBootException("online保存表单数据异常:系统未找到当前登陆用户信息");
		}
		for (OnlCgformField item : fieldList) {
			String key = item.getDbFieldName();
			if(null==key) {
				log.info("--------online修改表单数据遇见空名称的字段------->>"+item.getId());
				continue;
			}
			//主键不改
			if(P_KEY.equals(key)) {
				continue;
			}
			//为空且不为标准字段则不入库
			if (json.get(key) == null && !(UPDATE_BY.equalsIgnoreCase(key) || UPDATE_TIME.equalsIgnoreCase(key) || SYS_ORG_CODE.equalsIgnoreCase(key))) {
				continue;
			}

			//赋值系统默认字段
			initSystemFileds(item, sysUser, json, UPDATE_BY, UPDATE_TIME, SYS_ORG_CODE);

			//数值/时间类型 值为空不改
			if("".equals(json.get(key))) {
				String dbType = item.getDbType();
				if(OnlineDbHandler.isNumField(dbType)||OnlineDbHandler.isDateField(dbType)) {
					continue;
				}
			}
			String sqlValue = OnlineDbHandler.initMybatisValueWithJdbcType(dataBase, item, json, params);
			sb.append(key+SQL_EQ+sqlValue+SQL_COMMA);
		}

		String condition = sb.toString();
		if(condition.endsWith(SQL_COMMA)) {
			condition = condition.substring(0,condition.length()-1);
		}
		String sql = "update "+getRealTableName(tbname)+" set "+condition+ SQL_WHERE_TRUE +SQL_AND + P_KEY + SQL_EQ +SQL_SQ+json.getString(P_KEY)+SQL_SQ;
		log.info("--表单设计器表单编辑sql-->"+sql);
		params.put("execute_sql_string", sql);
		return params;
	}


	/**
	 * 设置树节点无子节点状态
	 * @param tbname
	 * @param filed
	 * @param id
	 * @return
	 */
	public static Map<String,Object> getTreeNodeNoChildSql(String tbname, String filed, String id){
		Map<String,Object> params = new HashMap<String,Object>();
		String sql = "update "+getRealTableName(tbname)+" set "+filed + SQL_EQ + SQL_SQ + 0 + SQL_SQ + SQL_WHERE_TRUE +SQL_AND + P_KEY + SQL_EQ +SQL_SQ + id + SQL_SQ;
		log.info("--修改树节点状态：为无子节点sql-->"+sql);
		params.put("execute_sql_string", sql);
		return params;
	}
	/**
	 * 拼接分类字典表的 查询条件 online分类字典树控件用到
	 * @param dictCode
	 * @return
	 */
	public static String getSysCatgoryCondition(String dictCode) {
		if(dictCode==null || "".equals(dictCode) || "0".equals(dictCode)) {
			return "";
		}
		return CATEGORY_CODE_NAME + SQL_LIKE +SQL_SQ+dictCode+"%"+SQL_SQ;
	}

	/**
	 * 获取真实表名
	 * @param tablename
	 * @return
	 */
	public static String getRealTableName(String tablename) {
		if(Pattern.matches("^[a-zA-z].*\\$\\d+$",tablename)) {
			//说明是复制表
			return tablename.substring(0,tablename.lastIndexOf(ONLINE_TABLE_SPLIT_STR));
		}
		return tablename;
	}

	/**
	 * 获取级联下拉组件的其他组件配置
	 * @param prop
	 * @param fieldList
	 * @param excludeFields
	 */
	public static void getLinkDownOtherField(LinkDownProperty prop ,List<OnlCgformField> fieldList,List<String> excludeFields){
		String str = prop.getDictTable();
		JSONObject json = JSONObject.parseObject(str);
		String linkField = json.getString("linkField");
		List<BaseColumn> list = new ArrayList<BaseColumn>();
		if(oConvertUtils.isNotEmpty(linkField)){
			String[] arr = linkField.split(",");
			for(OnlCgformField item:fieldList){
				String field = item.getDbFieldName();
				for(String key:arr){
					if(key.equals(field)){
                        excludeFields.add(field);
						list.add(new BaseColumn(item.getDbFieldTxt(),field));
						break;
					}
				}
			}
		}
		prop.setOtherColumns(list);
	}

	/**
	 *上传online图片，返回数据库存储路径
	 * @param data
	 * @param basePath
	 * @param uploadType local minio alioss
	 * @return
	 */
	public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
		return CommonUtils.uploadOnlineImage(data,basePath,bizPath,uploadType);
	}

	/**
	 * 获取是图片的列集合
	 * @param fieldList
	 * @return
	 */
	public static List<String> getImageColumnList(List<OnlCgformField> fieldList){
		List<String> ls = new ArrayList<String>();
		for(OnlCgformField field:fieldList){
			if(IMAGE.equals(field.getFieldShowType())){
				ls.add(field.getDbFieldTxt());
			}
		}
		return ls;
	}

	/**
	 * 获取子表图片的列集合
	 * @param fieldList
	 * @param pre
	 * @return
	 */
	public static List<String> getSubImageColumnList(List<OnlCgformField> fieldList,String pre){
		List<String> ls = new ArrayList<String>();
		for(OnlCgformField field:fieldList){
			if(IMAGE.equals(field.getFieldShowType())){
				ls.add(pre+"_"+field.getDbFieldTxt());
			}
		}
		return ls;
	}

	/**
	 * 生成id的方法（分布式ID算法twitter）
	 */
	public static String randomId(){
		long id = IdWorker.getId();
		return String.valueOf(id);
	}

	/**
	* online 统一转换友好异常提醒信息
	*/
	public static String getOnlineErrorMsg(Exception e){
		String errorMsg = (e.getCause()!=null? e.getCause().getMessage(): e.getMessage());
		if(errorMsg.indexOf("ORA-01452")!=-1){
			errorMsg = "ORA-01452: 无法 CREATE UNIQUE INDEX; 找到重复的关键字";
		}else if(errorMsg.indexOf("duplicate key")!=-1){
			errorMsg = "无法 CREATE UNIQUE INDEX; 找到重复的关键字";
		}
		return errorMsg;
	}

	/**
	 * 获取JEditableTable列需要的类型字符串
	 */
	private static String getJEditableTableColumnsType(OnlCgformField item) {
		if("checkbox".equals(item.getFieldShowType())) {
			return "checkbox";
		}else if("list".equals(item.getFieldShowType())) {
			return "select";
		}else if("switch".equals(item.getFieldShowType())) {
			return "switch";
		}else if("image".equals(item.getFieldShowType())
				|| "file".equals(item.getFieldShowType())
				|| "radio".equals(item.getFieldShowType())
				|| "popup".equals(item.getFieldShowType())
				|| "list_multi".equals(item.getFieldShowType())
				|| "sel_search".equals(item.getFieldShowType())) {
			return item.getFieldShowType();
		}else if("datetime".equals(item.getFieldShowType())) {
			return "datetime";
		}else if("date".equals(item.getFieldShowType())) {
			return "date";
		}else if("int".equals(item.getDbType())) {
			return "inputNumber";
		}else if("double".equals(item.getDbType())||"BigDecimal".equals(item.getDbType())) {
			return "inputNumber";
		}else {
			return "input";
		}
		/*	{ title: '文本框', value: 'text' },
        { title: '密码', value: 'password' },
        { title: '单选框', value: 'radio' },
        { title: '多选', value: 'checkbox' },
        { title: '日期(yyyy-MM-dd)', value: 'date' },
        { title: '日期（yyyy-MM-dd HH:mm:ss）', value: 'datetime' },
        { title: '文件', value: 'file' },
        { title: '多行文本', value: 'textarea' },
        { title: '下拉框', value: 'list' },
        { title: 'popup弹出框', value: 'popup' },
        { title: '图片', value: 'image' },
        { title: 'UE编辑器', value: 'umeditor' },
        { title: '树控件', value: 'tree' }*/
		 /* normal: 'normal',
		  input: 'input',
		  inputNumber: 'inputNumber',
		  checkbox: 'checkbox',
		  select: 'select',
		  date: 'date',
		  datetime: 'datetime'*/
		/*{ title: 'String', value: 'string' },
        { title: 'Integer', value: 'int' },
        { title: 'Double', value: 'double' },
        { title: 'Date', value: 'Date' },
        { title: 'BigDecimal', value: 'BigDecimal' },
        { title: 'Text', value: 'Text' },
        { title: 'Blob', value: 'Blob' }*/
	}


	/** 当前系统数据库类型 */
	private static String DATABSE_TYPE;
	/**
	 * 获取系统数据库类型
	 */
	private static String getDatabseType(){
		if(oConvertUtils.isNotEmpty(DATABSE_TYPE)){
			return DATABSE_TYPE;
		}
		try {
			ISysBaseAPI sysBaseAPI = ApplicationContextUtil.getContext().getBean(ISysBaseAPI.class);
			DATABSE_TYPE = sysBaseAPI.getDatabaseType();
			return DATABSE_TYPE;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return DATABSE_TYPE;
	}

}
